package Runde4;
import java.util.Scanner;

public class ReplaceableTree extends StringTree{

	/**
	 * @precondition root.length() > 0 and root != NULL
	 * @postcondition Creates a new tree with given a root node, labeled with the given param
	 * @param root - ReplaceableTree's new root-node
	 * @throws InvalidParamException - if param root is NULL or an empty string
	 */
	public ReplaceableTree(String root) throws InvalidParamException  {
		super(root);
	}

	/**
	 * @precondition node.length() > 0 and node != NULL
	 * @postcondition Adds a node with given string as label (does nothing at all if wrong params are given)
	 * @param node - label of the node that should be added
	 */
	public void add(String node) {
		try {
			checkParam(node);
			MyQueue mQ = new MyQueue();
			mQ.push(root);
			boolean notFound = true;
			while (notFound) {
				Node currentNode = mQ.pop();
				if (currentNode.getLeftChild() == null) {
					currentNode.setLeftChild(new Node(node));
					notFound = false;
				} else if (currentNode.getRightChild() == null) {
					currentNode.setRightChild(new Node(node));
					notFound = false;
				} else {
					mQ.push(currentNode.getLeftChild());
					mQ.push(currentNode.getRightChild());
				}
			}
		} catch (InvalidParamException e) {
			//Do nothing
		}
	}
	
	/**
	 * @precondition subTree.length()>0, "valid" position and subTree
	 * @postcondition replaces node and children on position with the given subTree (does nothing at all if wrong params are given)
	 * @param position - position which should be replaced
	 * @param subTree - new subTree on given position
	 */
	public void replace(String position, String subTree) {
		Node parent = root;
		Node child = root;
		Scanner s = new Scanner(position).useDelimiter(" ");
		String temp = "";
		try {
			while(s.hasNext()) {
				temp = s.next();
				parent = child;
				if(temp.equals("left")) {
					child = child.getLeftChild();
				} else if(temp.equals("right")) {
					child = child.getRightChild();
				}
			}
		} catch (NullPointerException e) {
			return;
		}
		try {
			Node replaceNode = createSubTree(subTree, 1);
			if(temp.equals("left"))
				parent.setLeftChild(replaceNode);
			else if(temp.equals("right"))
				parent.setRightChild(replaceNode);
			else
				root = replaceNode;
		} catch (InvalidParamException e) {}
	}
	
	/**
	 * @precondition level > 0
	 * @postcondition splits given subTree in left and right subTrees and creates nodes
	 * @param subTree - tree to split
	 * @param level - level inside the tree
	 * @throws InvalidParamException - if subTree is not correct formatted
	 */
	private Node createSubTree(String subTree, int level) throws InvalidParamException {
		Scanner s = new Scanner(subTree).useDelimiter("\n");
		String current = "";
		if(s.hasNext())
			current = s.next();
		int posMinus = level*2;
		
		String temp;
		String left = "";
		String right = "";
		if(s.hasNext())
			right = s.next()+"\n";
		while(s.hasNext()) {
			temp = s.next();
			if(temp.indexOf('*') == posMinus) {
				left = right;
				right = "";
			}
			right += temp+"\n";
		}
		if(right.length()>1 && left.length()<1)
			throw new InvalidParamException("invalid subtree");
		
		current = current.replace('*', ' ');
		current = current.trim();
		if(current.length()>=1) {
			Node currentNode = new Node(current);
			currentNode.setLeftChild(createSubTree(left, level+1));
			currentNode.setRightChild(createSubTree(right, level+1));
			return currentNode;
		} else
			return null;
	}

}
